package afcp.alumni.action.event;

import net.sourceforge.stripes.action.Message;
import net.sourceforge.stripes.action.Resolution;
import net.sourceforge.stripes.action.UrlBinding;
import net.sourceforge.stripes.security.Secure;
import net.sourceforge.stripes.validation.LocalizableError;
import net.sourceforge.stripes.validation.Validate;
import net.sourceforge.stripes.validation.ValidateNestedProperties;
import net.sourceforge.stripes.validation.ValidationErrors;
import net.sourceforge.stripes.validation.ValidationMethod;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import afcp.alumni.action.base.EventAction;
import afcp.alumni.action.page.AdminAction;
import afcp.alumni.model.db.Member;
import afcp.alumni.model.db.Role;
import afcp.alumni.service.MemberService;
import afcp.alumni.service.SF;

@UrlBinding(ManageMemberAction.URL)
@Secure(roles = MemberService.ROLE_ADMIN)
public class ManageMemberAction extends EventAction {

	@Override
	protected String fromUrl() {
		return AdminAction.URL;
	}

	@Override
	public String getUrl() {
		return URL;
	}

	@Override
	public Resolution view() {
		return fromRedirect();
	}

	public static final String URL = "/memberaction";
	
	private static final Log logger = LogFactory.getLog(ManageMemberAction.class);
	
	
	
	


	// Add member form

	private MemberService memberService = SF.member();

	// These properties are related to the fields with the same name ("name"
	// attribute in the input tags) in the JSP.
	@ValidateNestedProperties({
			@Validate(field = "login.id", required = true, on = "createMember", minlength = 2),
			@Validate(field = "firstName", required = true, on = "createMember"),
			@Validate(field = "lastName", required = true, on = "createMember"),
			@Validate(field = "password", required = true, on = "createMember", minlength = 2/*, converter = PasswordEncoder.class*/),
			@Validate(field = "roles.id", required = true, on = "createMember"),
	})
	private Member newMember;
	// @Validate(field = "role", required = true, on = "createMember")

	/**
	 * Getter to display in the JSP which member has just been added.
	 * 
	 * @return the {@link Member} object of the added Member
	 */
	public Member getNewMember() {
		return newMember;
	}

	/**
	 * Setter to fill the field {@link #newMember} with the form values in the
	 * JSP.
	 * 
	 * @param The
	 *            member set and filled with the form
	 */
	public void setNewMember(Member newMember) {
		this.newMember = newMember;
	}

//	@Validate(required = true, on = "createMember")
//	private String role;
//
//	public String getRole() {
//		return role;
//	}
//
//	public void setRole(String role) {
//		this.role = role;
//	}
	
//	private Role roleLoaded;

	@ValidationMethod(on = "createMember")
	public void completeAndValidateUser(ValidationErrors errors) {
		if (memberService.memberExists(newMember)) {
			errors.addGlobalError(new LocalizableError("database.alreadyexists"));
			newMember = null; // Pour ne pas afficher sur la JSP qu'il a été
								// créé
		} else if (!memberService.roleExists(newMember)) {
			errors.addGlobalError(new LocalizableError("database.role.dontexist"));
		}
	}

	public static final String NEWMEMBER_MSG_KEY = "newmember";
	
	/**
	 * Method called by the new member form. Add a member to the datastore by
	 * calling the service method
	 * {@link MemberService#addOrUpdateMember(Member)}.
	 * 
	 * @return
	 */
	public Resolution createMember() {
//		newMember.setRole(roleLoaded);
		// TODO replace with this.getRoles()

		// Delegate to the service.
		boolean succeeded = memberService.addOrUpdateMember(newMember);
		Message memberAdded;
		// printing the result
		if (succeeded) {
//			logger.info("Nouveau membre. Prénom : " + newMember.getFirstName()
//			+ ", nom : " + newMember.getLastName());
			memberAdded = msgObj("message.newmember", newMember.getFirstName(), newMember.getLastName());
			logger.info(msgToStr(memberAdded));
		} else {
			memberAdded = msgObj("message.newmember.failed", newMember.getFirstName(), newMember.getLastName());
			logger.error(msgToStr(memberAdded));
//			String errorMessage = "Le membre " + newMember.getFirstName() + " "
//			+ newMember.getLastName()
//			+ " n'a pas pu être ajouté. Un problème est survenu.";
////			error(errorMessage);
//			logger.error(errorMessage);
		}
		addFlashScope(NEWMEMBER_MSG_KEY, memberAdded);
		return fromRedirect();
	}

	// End add member form

	
	// Delete member form

	private Member deletedMember;

	/**
	 * Getter to display in the JSP which member has just been deleted.
	 * 
	 * @return The {@link Member} object of the deleted Member
	 */
	public Member getDeletedMember() {
		return deletedMember;
	}

	@Validate(required = true, on = "removeMember")
	private String idDeletedMember;

	public void setIdDeletedMember(String idDeletedMember) {
		this.idDeletedMember = idDeletedMember;
	}

	public static final String DELETEMEMBER_MSG_KEY = "deletemember";

	/**
	 * Method called by the member deletion form. Remove a member from the
	 * datastore by calling the service method
	 * {@link MemberService#removeMemberFromKeyString(String)}.
	 * 
	 * @return
	 */
	public Resolution removeMember() {
		// delegate to the service. Since the member already exists, the bean
		// will be made by the DAO.
		deletedMember = memberService.removeMemberFromKeyString(idDeletedMember);
//		logger.info("Membre supprimé. Identifiant : "
//				+ idDeletedMember
//				+ (deletedMember == null ? "" : ", prénom : "
//						+ deletedMember.getFirstName() + ", nom : "
//						+ deletedMember.getLastName()));
		Message memberDeleted;
		if (deletedMember == null) {
			memberDeleted = msgObj("message.deletemember", idDeletedMember);
		} else {
			memberDeleted = msgObj("message.deletemember.withname", idDeletedMember, deletedMember.getFirstName(), deletedMember.getLastName());
		}
		logger.info(msgToStr(memberDeleted));
		addFlashScope(DELETEMEMBER_MSG_KEY, memberDeleted);

		return fromRedirect();
	}

	// End delete member form

	

	// Formulaire d'ajout de rôles

	@ValidateNestedProperties({
			@Validate(field = "id", required = true, on = "addRole"),
			@Validate(field = "label", required = true, on = "addRole") })
	private Role newRole;

	public Role getNewRole() {
		return newRole;
	}

	public void setNewRole(Role newRole) {
		this.newRole = newRole;
	}

	@ValidationMethod(on = "addRole")
	public void validateRole(ValidationErrors errors) {
		if (memberService.roleExists(newRole)) {
			errors.addGlobalError(new LocalizableError("database.alreadyexists"));
			newRole = null; // Pour ne pas afficher sur la JSP qu'il a été créé
		}
	}

	public static final String NEWROLE_MSG_KEY = "newrole";

	public Resolution addRole() {
		memberService.addOrUpdateRole(newRole);
		addFlashScope(NEWROLE_MSG_KEY, msgObj("message.newrole", newRole.getLabel()));
		return fromRedirect();
	}

	// End formulaire d'ajout de rôles
	

	// delete role button

	private Role deletedRole;

	/**
	 * Getter to display in the JSP which member has just been deleted.
	 * 
	 * @return The {@link Member} object of the deleted Member
	 */
	public Role getDeletedRole() {
		return deletedRole;
	}

	@Validate(required = true, on = "removeRole")
	private String idDeletedRole;

	public void setIdDeletedRole(String idDeletedRole) {
		this.idDeletedRole = idDeletedRole;
	}

	public static final String DELETEROLE_MSG_KEY = "deleterole";

	/**
	 * Method called by the role deletion form. Removes a role from the
	 * datastore by calling the service method
	 * {@link MemberService#removeRole(String)}.
	 * 
	 * @return
	 */
	public Resolution removeRole() {
		// delegate to the service. Since the member already exists, the bean
		// will be made by the DAO.
		deletedRole = memberService.removeRole(idDeletedRole);
		logger.info("Rôle supprimé. Identifiant : "
				+ idDeletedRole
				+ (deletedRole == null ? "" : ", id : " + deletedRole.getId()
						+ ", libellé : " + deletedRole.getLabel()));
		Message roleDeleted;
		if (deletedMember == null) {
			roleDeleted = msgObj("message.deleterole", idDeletedRole);
		} else {
			roleDeleted = msgObj("message.deleterole.withlabel", idDeletedRole, deletedRole.getLabel());
		}
		addFlashScope(DELETEROLE_MSG_KEY, roleDeleted);

		return fromRedirect();
	}

	// end delete role button
	
	
	
	

}
